﻿using System;
using System.Collections.Generic;
using PokemonBattle.BattleNetwork;
using PBO.Data;
using System.Drawing;
using PBO.Game;

namespace PBO.Game.BattleClass
{
    public partial class Pokemon
    {
        protected BaseStats Ev { get; private set; }
        protected BaseStats Iv { get; private set; }
        protected BaseStats BaseValue { get; private set; }

        public int GetAttack(bool ct = false)
        {
            int value = 0;
            int lv = AttackLV;
            if (GetSelTrait() == Trait.Simple)
                lv *= 2;
            if (MyTeam.ground.Unaware && GetSelTrait() != Trait.MoldBreaker)
                lv = 0;
            if (ct && lv < 0)
                lv = 0;
            value = CalculateAbility(GetAttackValue(), lv);

            if (State == PokemonState.Burn && !(GetSelTrait() == Trait.Guts))
                value = Convert.ToInt32(Math.Truncate(value * 0.5));
            if (GetSelTrait() == Trait.HugePower)
                value *= 2;
            if (GetSelTrait() == Trait.PurePower)
                value *= 2;
            if (GetSelTrait() == Trait.Guts && State != PokemonState.No)
                value = Convert.ToInt32(Math.Truncate(value * 1.5));
            if (GetSelTrait() == Trait.Hustle)
                value = Convert.ToInt32((Math.Truncate(value * 1.5)));
            if (GetSelTrait() == Trait.SlowStart && BattleState.slowStartCounter != 0)
                value = Convert.ToInt32(Math.Truncate(value * 0.5));
            if (GetItem() == Item.LightBall && Data.Number == 25)
                value *= 2;
            if (GetItem() == Item.ThickClub && (Data.Number == 105 || Data.Number == 104))
                value *= 2;
            if (GetItem() == Item.ChoiceBand)
                value = Convert.ToInt32(Math.Truncate(value * 1.5));
            return value;
        }

        public int GetDefence(Pokemon target = null, bool ct = false, bool miracleRoomRedirected = false)
        {
            if (MyTeam.ground.MiracleRoom && !miracleRoomRedirected)
            {
                return GetSpDefence(target, ct, true);
            }
            int value = 0;
            int lv = DefenceLV;
            if (GetSelTrait() == Trait.Simple && target != null && target.GetSelTrait() != Trait.MoldBreaker)
                lv *= 2;
            if (MyTeam.ground.Unaware)
                lv = 0;

            if (ct && lv > 0)
                lv = 0;
            value = CalculateAbility(GetDefenceValue(), lv);

            if (target != null && target.GetSelTrait() != Trait.MoldBreaker && GetSelTrait() == Trait.MarvelScale && State != PokemonState.No)
                value = Convert.ToInt32(Math.Truncate(value * 1.5));
            if (GetItem() == Item.MetalPowder && this.Data.Number == 132)
                value *= 2;
            return value;
        }

        public int Speed
        {
            get
            {
                double value = 0;
                int lv = SpeedLV;
                if (GetSelTrait() == Trait.Simple)
                    lv *= 2;
                if (MyTeam.ground.Unaware)
                    lv = 0;

                value = CalculateAbility(SpeedValue, lv);

                if (State == PokemonState.Paralysis && !(GetSelTrait() == Trait.QuickFeet))
                    value = value * 0.25;
                if (MyTeam.Group.WithWind)
                    value *= 2;
                if (GetSelTrait() == Trait.SwiftSwim && MyTeam.ground.Weather == Weather.Rainy)
                    value *= 2;
                if (GetSelTrait() == Trait.Chlorophyll && MyTeam.ground.Weather == Weather.Sunny)
                    value *= 2;
                if (GetSelTrait() == Trait.Unburden && BattleState.traitRaised)
                    value *= 2;
                if (GetSelTrait() == Trait.QuickFeet && State != PokemonState.No)
                    value = value * 1.5;
                if (GetSelTrait() == Trait.SlowStart && BattleState.slowStartCounter != 0)
                    value = value * 0.5;
                if (GetItem() == Item.QuickPowder && this.Data.Number == 132)
                    value *= 2;
                if (GetItem() == Item.ChoiceScarf)
                    value = value * 1.5;
                if (GetItem() == Item.IronBall || GetItem() == Item.MachoBrace)
                    value = value * 0.5;
                if (MyTeam.Group.moor)
                    value *= 0.25;

                return Convert.ToInt32(Math.Truncate(value));
            }
        }

        public int GetSpAttack(bool ct = false)
        {
            double value = 0;
            int lv = SpAttackLV;
            if (GetSelTrait() == Trait.Simple)
                lv *= 2;
            if (MyTeam.ground.Unaware && GetSelTrait() != Trait.MoldBreaker)
                lv = 0;

            if (ct && lv < 0)
                lv = 0;
            value = CalculateAbility(SpAttackValue, lv);

            if (GetSelTrait() == Trait.SolarPower && MyTeam.ground.Weather == Weather.Sunny)
                value *= 1.5;
            if (GetItem() == Item.LightBall && Data.Number == 25)
                value *= 2;
            if (GetItem() == Item.Deepseatooth && Data.Number == 366)
                value *= 2;
            if (GetItem() == Item.SoulDew && (Data.Number == 380 || Data.Number == 381))
                value *= 1.5;
            if (GetItem() == Item.ChoiceSpecs)
                value *= 1.5;
            if (this.Friend != null && this.Friend.HealthPower != 0)
            {
                if ((GetSelTrait() == Trait.Plus && this.Friend.GetSelTrait() == Trait.Minus) || (GetSelTrait() == Trait.Minus && this.Friend.GetSelTrait() == Trait.Plus))
                {
                    value = Math.Truncate(value * 1.5);
                }
            }
            return Convert.ToInt32(value);
        }

        public int GetSpDefence(Pokemon target = null, bool ct = false, bool miracleRoomRedirected = false)
        {
            if (MyTeam.ground.MiracleRoom && !miracleRoomRedirected)
            {
                return GetDefence(target, ct, true);
            }
            int value = 0;
            int lv = SpDefenceLV;
            if (GetSelTrait() == Trait.Simple && target != null && target.GetSelTrait() != Trait.MoldBreaker)
                lv *= 2;
            if (MyTeam.ground.Unaware)
                lv = 0;

            if (ct && lv > 0)
                lv = 0;
            value = CalculateAbility(SpDefenceValue, lv);

            if (GetItem() == Item.Deepseascale && Data.Number == 366)
                value *= 2;
            if (GetItem() == Item.SoulDew && (Data.Number == 380 || Data.Number == 381))
                value = Convert.ToInt32(Math.Truncate(value * 1.5));
            return value;
        }

        public static int CalculateAbility(int value, int lv)
        {
            if (lv >= 0)
            {
                lv = Math.Min(lv, 6);
                value = Convert.ToInt32(Math.Truncate(value * (2 + lv) * 0.5));
            }
            else
            {
                lv = Math.Max(lv, -6);
                value = Convert.ToInt32(Math.Truncate((double)value * 2 / (2 - lv)));
            }
            return value;
        }

        public int GetAttackValue(bool powerTrickRedirected = false)
        {
            if (BattleState.powerTrick && !powerTrickRedirected)
            {
                return GetDefenceValue(true);
            }

            return BattleState.tempAttack != 0 ? BattleState.tempAttack : this.BaseValue.Atk;
        }
        public void SetAttackValue(int value, bool powerTrickRedirected = false)
        {
            if (BattleState.powerTrick && !powerTrickRedirected)
            {
                SetDefenceValue(value, true);
            }
            BattleState.tempAttack = value;
        }
        public int GetDefenceValue(bool powerTrickRedirected = false)
        {
            if (BattleState.powerTrick && !powerTrickRedirected)
            {
                return GetAttackValue(true);
            }
            if (BattleState.tempDefence != 0)
                return BattleState.tempDefence;
            return this.BaseValue.Def;
        }
        public void SetDefenceValue(int value, bool powerTrickRedirected = false)
        {
            if (BattleState.powerTrick && !powerTrickRedirected)
            {
                SetAttackValue(value, true);
            }
            BattleState.tempDefence = value;
        }
        public int SpeedValue
        {
            get
            {
                if (BattleState.tempSpeed != 0)
                    return BattleState.tempSpeed;
                return this.BaseValue.Speed;
            }
            set { BattleState.tempSpeed = value; }
        }
        public int SpAttackValue
        {
            get
            {
                if (BattleState.tempSAttack != 0)
                    return BattleState.tempSAttack;
                return this.BaseValue.SpAtk;
            }
            set { BattleState.tempSAttack = value; }
        }
        public int SpDefenceValue
        {
            get
            {
                if (BattleState.tempSDefence != 0)
                    return BattleState.tempSDefence;
                return this.BaseValue.SpDef;
            }
            set { BattleState.tempSDefence = value; }
        }
    }
}
